package com.socio.threads;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.socio.model.ClientUser;
import com.socio.utils.SocioUtils;

public class BackendThread extends Thread {
	
	public enum BackendThreadModes { GetLeaderboard, GetSettings, SubmitNickname };
	
	public enum BackendThreadMessages { TroubleGettingLeaderboard, NoDataFound, SearchSuccessful, 
		SettingsSuccessful, TroubleGettingSettings, TroubleSubmittingNickname, SubmitSuccessful };

	// mode in which the thread should function in
	private BackendThreadModes mode;

	// Handler for communicating back with regular thread
	private Handler handler;

	// Bundle for obtaining extra parameter
	private Map<String, Object> extraParams;

	public BackendThread(Handler handler, BackendThreadModes mode, Map<String, Object> extraParams) {
		this.extraParams = extraParams;
		this.mode = mode;
		this.handler = handler;
	}

	@Override
	public void run() {

		switch (this.mode) {
		case GetLeaderboard:
			getLeaderboard();
			break;
		case GetSettings:
			getSettings();
			break;
		case SubmitNickname:
			submitNickname();
			break;
		default:
			break;
		}

	}
	
	/**
	 * Get leaderboard
	 */
	private void getLeaderboard() {
		// get Uri Builder, and url parameters
		Uri.Builder uriBuilder = (Uri.Builder)extraParams.get("uriBuilder");
		
		List<ClientUser> clientUsers;
		try {
			String jsonString = SocioUtils.getResponseFromURL(uriBuilder);
			
			Gson gson = new Gson();
			Type collectionType = new TypeToken<List<ClientUser>>(){}.getType();
			clientUsers = gson.fromJson(jsonString, collectionType);
		} catch (Exception e) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleGettingLeaderboard);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		if(clientUsers == null || clientUsers.size() == 0) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.NoDataFound);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
			
		Message toMain = handler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putSerializable("message type", BackendThreadMessages.SearchSuccessful);
		toMain.setData(bundle);
		toMain.obj = clientUsers;
		handler.sendMessage(toMain);
	}
	
	private void submitNickname() {
		// get Uri Builder, and url parameters
		Uri.Builder uriBuilder = (Uri.Builder)extraParams.get("uriBuilder");
		String json = (String)extraParams.get("json");
		
		String addSuccessful;
		try {
			addSuccessful = SocioUtils.postStringToURL(uriBuilder, json);
		} catch (Exception e) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleSubmittingNickname);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		if(addSuccessful.equalsIgnoreCase("false")) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleSubmittingNickname);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		Message toMain = handler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putSerializable("message type", BackendThreadMessages.SubmitSuccessful);
		toMain.setData(bundle);
		handler.sendMessage(toMain);
	}
	
	private void getSettings() {
		// get Uri Builder, and url parameters
		Uri.Builder uriBuilder = (Uri.Builder)extraParams.get("uriBuilder");
		
		ClientUser clientUser;
		try {
			String jsonString = SocioUtils.getResponseFromURL(uriBuilder);
			
			Gson gson = new Gson();
			clientUser = gson.fromJson(jsonString, ClientUser.class);
		} catch (Exception e) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleGettingLeaderboard);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
		
		if(clientUser == null) {
			Message msg = handler.obtainMessage();
			Bundle bundle = new Bundle();
			bundle.putSerializable("message type", BackendThreadMessages.TroubleGettingSettings);
			msg.setData(bundle);
			handler.sendMessage(msg);
			return;
		}
			
		Message toMain = handler.obtainMessage();
		Bundle bundle = new Bundle();
		bundle.putSerializable("message type", BackendThreadMessages.SettingsSuccessful);
		toMain.setData(bundle);
		toMain.obj = clientUser;
		handler.sendMessage(toMain);
	}
}
